#pragma once
#include "CXcpObjectBase.h"
#include "IObject.h"
#include "CXcpObjectThreadSafeAddRefPolicy.h"


class CHardwareCompositor;
class CUIElement;
class CWeakRefManager;
class CompositorScheduler;


class CMetaCompositor :
	public CXcpObjectBase<IObject,CXcpObjectThreadSafeAddRefPolicy>
{
private: 
	CMetaCompositor(struct IPALGraphicsDeviceManager *, struct ICoreCompositorScheduler *);
	virtual ~CMetaCompositor();
public: 
	virtual XUINT32 AddRef();
	virtual XUINT32 Release();
	static HRESULT Create(struct IPALGraphicsDeviceManager * pIGraphicsDeviceManager, struct ICoreCompositorScheduler * pICompositorScheduler, CMetaCompositor * * ppMetaCompositor);
	HRESULT ResetPresentMethod(struct IPALPresentTarget * pIPresentTarget);
	HRESULT EnsureHardwareCompositors(CWeakRefManager * pWeakRefManager, XBOOL useSeparateSwapChains, struct IXcpBrowserHost * pHost, CUIElement * * ppSecondaryRoots, XUINT32 secondaryRootCount);
	CHardwareCompositor * GetPrimaryHardwareCompositor();
	CHardwareCompositor * GetHardwareCompositor(CUIElement * pSecondaryRoot);
	XBOOL LastRenderWalkUsedSeparateSwapChains();
	XBOOL IsPresentMethodInitialized();
	HRESULT SubmitRetarget(XBOOL wakeupCompositionThread, struct IPALPresentTarget * pIPresentTarget);
	HRESULT EnsurePresent(struct IPALPresentParameters * pIPresentParameters);
	HRESULT HandleRenderThreadError();
	HRESULT SubmitClear(XUINT32 uColor);
	HRESULT PushFrameToCompositor(XBOOL renderStateChangedToEnabled);
	void WaitForGPUWork();
	struct ICoreCompositorScheduler * GetCompositorScheduler();
	void FreeAllHardwareCompositorsBuffers();
	struct IPALDCompTreeHost * GetDCompTreeHost();
	HRESULT SubmitRenderStateChanged(XBOOL isRenderEnabled);
private: 
	HRESULT ReleaseCompositor(CHardwareCompositor * pCompositor);
	HRESULT CreateHardwareCompositor(struct IPALPresentTarget * pIPresentTarget, CHardwareCompositor * * ppHardwareCompositor);
	HRESULT ReleaseCompositors();
	HRESULT MatchElementsWithCompositors(CWeakRefManager * pWeakRefManager, CUIElement * * ppSecondaryRoots, XUINT32 secondaryRootCount, xvector<CUIElement *> * pUnmatchedSecondaryRootsNoRef, xvector<CHardwareCompositor *> * pUnmatchedCompositorsNoRef);
	HRESULT PairUnmatchedElementsWithUnmatchedCompositors(CWeakRefManager * pWeakRefManager, xvector<CUIElement *> * pUnmatchedSecondaryRootsNoRef, xvector<CHardwareCompositor *> * pUnmatchedCompositorsNoRef, XUINT32 * pUnmatchedSecondaryRootIndex, XUINT32 * pUnusedCompositorIndex);
	HRESULT CreateCompositorsForUnmatchedElements(CWeakRefManager * pWeakRefManager, struct IXcpBrowserHost * pHost, xvector<CUIElement *> * pUnmatchedSecondaryRootsNoRef, XUINT32 unmatchedSecondaryRootIndex);
	struct IPALGraphicsDeviceManager * m_pGraphicsDeviceManagerNoRef;
	CompositorScheduler * m_pCompositorScheduler;
	XBOOL m_lastRenderWalkUsedSeparateSwapChains;
	xvector<CHardwareCompositor *> m_compositors;
};